﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;

using Client.Common;
using Client.DAL;
using Microsoft.Win32;
using Models;

using Newtonsoft.Json;

using Panuon.UI.Silver;

using Prism.Commands;
using Prism.Mvvm;

using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using System.IO;

namespace Client.ViewModels
{
    public class CustomManageViewModel : BindableBase
    {
        #region 绑定属性

        #region 管理窗口

        //客户类别列表
        private ObservableCollection<CustomCateModel> _cateList;

        public ObservableCollection<CustomCateModel> CateList
        {
            get { return _cateList; }
            set { SetProperty(ref _cateList, value, "CateList"); }
        }

        //显示的列表
        private ObservableCollection<CustomModel> _showList;

        public ObservableCollection<CustomModel> ShowList
        {
            get { return _showList; }
            set { SetProperty(ref _showList, value, "ShowList"); }
        }

        //查找关键词
        private string _keyword;

        public string Keyword
        {
            get { return _keyword; }
            set { SetProperty(ref _keyword, value, "Keyword"); }
        }

        //客户类别选择项
        private object _selectedCate;

        public object SelectedCate
        {
            get { return _selectedCate; }
            set { SetProperty(ref _selectedCate, value, "SelectedCate"); }
        }

        //修改类别按钮状态
        private bool _btnCateEditWorking;

        public bool BtnCateEditWorking
        {
            get { return _btnCateEditWorking; }
            set { SetProperty(ref _btnCateEditWorking, value, "BtnCateEditWorking"); }
        }

        //删除类别按钮状态
        private bool _btnCateDelWorking;

        public bool BtnCateDelWorking
        {
            get { return _btnCateDelWorking; }
            set { SetProperty(ref _btnCateDelWorking, value, "BtnCateDelWorking"); }
        }

        //类别载入界面转圈图标状态
        private bool _cateLoading;

        public bool CateLoading
        {
            get { return _cateLoading; }
            set { SetProperty(ref _cateLoading, value, "CateLoading"); }
        }

        //类别载入中图层状态
        private Visibility _cateRunning;

        public Visibility CateRunning
        {
            get { return _cateRunning; }
            set { SetProperty(ref _cateRunning, value, "CateRunning"); }
        }

        //客户列表载入中状态
        private Visibility _custRunning;

        public Visibility CustRunning
        {
            get { return _custRunning; }
            set { SetProperty(ref _custRunning, value, "CustRunning"); }
        }

        //客户列表转圈图标状态
        private bool _custLoading;

        public bool CustLoading
        {
            get { return _custLoading; }
            set { SetProperty(ref _custLoading, value, "CustLoading"); }
        }

        //客户启用按钮状态
        private bool _btnCustEnableWorking;

        public bool BtnCustEnableWorking
        {
            get { return _btnCustEnableWorking; }
            set { SetProperty(ref _btnCustEnableWorking, value, "BtnCustEnableWorking"); }
        }

        //客户禁用按钮状态
        private bool _btnCustDisableWorking;

        public bool BtnCustDisableWorking
        {
            get { return _btnCustDisableWorking; }
            set { SetProperty(ref _btnCustDisableWorking, value, "BtnCustDisableWorking"); }
        }

        //客户列表刷新按钮状态
        private bool _btnCustRefreshWorking;

        public bool BtnCustRefreshWorking
        {
            get { return _btnCustRefreshWorking; }
            set { SetProperty(ref _btnCustRefreshWorking, value, "BtnCustRefreshWorking"); }
        }

        //客户信息列表
        private ObservableCollection<CustomModel> _custList;

        public ObservableCollection<CustomModel> CustList
        {
            get { return _custList; }
            set { SetProperty(ref _custList, value, "CustList"); }
        }

        //选择的客户
        private object _selectedCust;

        public object SelectedCust
        {
            get { return _selectedCust; }
            set { SetProperty(ref _selectedCust, value, "SelectedCust"); }
        }

        //是否显示禁用
        private bool _showDisabledCustom;

        public bool ShowDisabledCustom
        {
            get { return _showDisabledCustom; }
            set { SetProperty(ref _showDisabledCustom, value, "ShowDisabledCustom"); }
        }

        #endregion 管理窗口

        #region 类别编辑窗口

        private CustomCateModel _cateEditCate;

        public CustomCateModel CateEditCate
        {
            get { return _cateEditCate; }
            set { SetProperty(ref _cateEditCate, value, "CateEditCate"); }
        }

        #endregion 类别编辑窗口

        #region 客户编辑窗口

        //客户信息主体
        private CustomModel _custEditCust;

        public CustomModel CustEditCust
        {
            get { return _custEditCust; }
            set { SetProperty(ref _custEditCust, value, "CustEditCust"); }
        }

        //保存按钮状态
        private bool _btnCustEditSaveWorking;

        public bool BtnCustEditSaveWorking
        {
            get { return _btnCustEditSaveWorking; }
            set { SetProperty(ref _btnCustEditSaveWorking, value, "BtnCustEditSaveWorking"); }
        }

        //类别列表
        private ObservableCollection<CustomCateModel> _custEditCateList;

        public ObservableCollection<CustomCateModel> CustEditCateList
        {
            get { return _custEditCateList; }
            set { SetProperty(ref _custEditCateList, value, "CustEditCateList"); }
        }

        //当前选择的类别
        private object _custEditSelectedCate;

        public object CustEditSelectedCate
        {
            get { return _custEditSelectedCate; }
            set { SetProperty(ref _custEditSelectedCate, value, "CustEditSelectedCate"); }
        }

        #endregion 客户编辑窗口

        #endregion 绑定属性

        #region 属性

        private Views.CustomCateEditView _cateEditWindow;
        private Views.CustomEditView _custEditWindow;

        #region 类别编辑窗口

        private string _cateEditOpenType = "new";

        #endregion 类别编辑窗口

        #region 客户编辑窗口

        private string _custEditOpenType = "new";

        #endregion 客户编辑窗口

        #endregion 属性

        #region 命令

        #region 客户管理窗口

        public DelegateCommand AddCateCommand { get; private set; }
        public DelegateCommand EditCateCommand { get; private set; }
        public DelegateCommand DelCateCommand { get; private set; }
        public DelegateCommand GetCateCommand { get; private set; }
        public DelegateCommand SelectCateCommand { get; private set; }

        public DelegateCommand CustAddCommand { get; private set; }
        public DelegateCommand CustEditCommand { get; private set; }
        public DelegateCommand CustEnableCommand { get; private set; }
        public DelegateCommand CustDisableCommand { get; private set; }
        public DelegateCommand CustRefreshCommand { get; private set; }
        public DelegateCommand SearchCommand { get; private set; }
        public DelegateCommand ExportCommand { get; private set; }

        #endregion 客户管理窗口

        #region 类别编辑窗口

        public DelegateCommand CateEditNewCommand { get; private set; }
        public DelegateCommand CateEditSaveCommand { get; private set; }

        #endregion 类别编辑窗口

        #region 客户编辑窗口

        public DelegateCommand CustEditNewCommand { get; private set; }
        public DelegateCommand CustEditSaveCommand { get; private set; }

        #endregion 客户编辑窗口

        #endregion 命令

        #region 构造函数

        public CustomManageViewModel()
        {
            CateList = new ObservableCollection<CustomCateModel>();
            BtnCateEditWorking = false;
            BtnCateDelWorking = false;
            CateLoading = false;
            CateRunning = Visibility.Hidden;
            CustLoading = false;
            CustRunning = Visibility.Hidden;
            CustList = new ObservableCollection<CustomModel>();
            ShowList = new ObservableCollection<CustomModel>();
            AddCateCommand = new DelegateCommand(OpenNewCustCate);
            EditCateCommand = new DelegateCommand(OpenEditCustCate);
            DelCateCommand = new DelegateCommand(DelCustCate);
            GetCateCommand = new DelegateCommand(GetCustCateList);
            CustAddCommand = new DelegateCommand(CustAdd);
            CustEditCommand = new DelegateCommand(CustEdit);
            CustEnableCommand = new DelegateCommand(CustEnable);
            CustDisableCommand = new DelegateCommand(CustDisable);
            CustRefreshCommand = new DelegateCommand(CustRefreshList);
            SelectCateCommand = new DelegateCommand(GetCustList);
            SearchCommand = new DelegateCommand(SearchCust);
            ExportCommand = new DelegateCommand(ExportCust);

            CateEditCate = new CustomCateModel();
            CateEditNewCommand = new DelegateCommand(CateEditNew);
            CateEditSaveCommand = new DelegateCommand(CateEditSave);

            CustEditCust = new CustomModel();
            CustEditCateList = new ObservableCollection<CustomCateModel>();
            CustEditNewCommand = new DelegateCommand(CustEditNew);
            CustEditSaveCommand = new DelegateCommand(CustEditSave);

            GetCustCateList();
        }

        #endregion 构造函数

        #region 方法

        #region 客户管理窗口

        #region 打开新建客户类别窗口

        private void OpenNewCustCate()
        {
            _cateEditWindow = new Views.CustomCateEditView
            {
                Title = "客户类别增加",
                Owner = Comm.Shell,
                DataContext = this
            };
            CateEditCate = new CustomCateModel();
            _cateEditWindow.ShowDialog();
            _cateEditWindow = null;
        }

        #endregion 打开新建客户类别窗口

        #region 打开修改客户类别窗口

        private StateModel getCateState;

        private async void OpenEditCustCate()
        {
            if (null == SelectedCate)
            {
                Comm.ShowErr("必须选择一个要修改的类别！", "类别修改");
                return;
            }
            if (!(SelectedCate is CustomCateModel ccm))
            {
                Comm.ShowErr("选择的类别不正确！", "类别修改");
                return;
            }
            BtnCateEditWorking = true;
            CateEditCate = new CustomCateModel { Id = ccm.Id };
            getCateState = new StateModel { CurStep = Steps.Send };
            void callback(RetModel rm)
            {
                if (getCateState.CurStep != Steps.Send)
                    return;
                getCateState.RM = rm;
                getCateState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            CustomSrv.GetCateInfo(callback, CateEditCate.Id);
            await getCateState.CheckState(10);
            BtnCateEditWorking = false;
            if (getCateState.CurStep != Steps.Succ)
            {
                Comm.ShowErr(getCateState.ErrStr, "类别修改");
            }
            else
            {
                CateEditCate = GenCate();
                if (CateEditCate is null)
                {
                    Comm.ShowErr(getCateState.ErrStr, "类别修改");
                }
                else
                {
                    _cateEditWindow = new Views.CustomCateEditView()
                    {
                        Title = "客户类别修改",
                        Owner = Comm.Shell,
                        DataContext = this
                    };
                    _cateEditOpenType = "edit";
                    _cateEditWindow.ShowDialog();
                    _cateEditWindow.Close();
                    _cateEditWindow = null;
                }
            }
        }

        private CustomCateModel GenCate()
        {
            CustomCateModel cate = null;
            try
            {
                if (getCateState.RM != null)
                    cate = JsonConvert.DeserializeObject<CustomCateModel>(getCateState.RM.Data.ToString());
            }
            catch (Exception ex)
            {
                getCateState.RM = getCateState.RM ?? new RetModel();
                getCateState.RM.ErrCode = "0000";
                getCateState.RM.ErrInfo = ex.Message;
            }
            return cate;
        }

        #endregion 打开修改客户类别窗口

        #region 删除客户类别

        private StateModel delCateState;

        private async void DelCustCate()
        {
            var rst = MessageBoxX.Show("是否确定要删除选定的客户类别？", "删除类别", Comm.Shell, MessageBoxButton.YesNo, new MessageBoxXConfigurations()
            {
                MessageBoxIcon = MessageBoxIcon.Info,
                MaxContentHeight = 240,
                MaxContentWidth = 240,
                WindowStartupLocation = WindowStartupLocation.CenterOwner,
                MessageBoxStyle = MessageBoxStyle.Modern,
                Topmost = false
            });
            if (rst != MessageBoxResult.Yes)
                return;
            if (SelectedCate is null || !(SelectedCate is CustomCateModel cm))
            {
                Comm.ShowErr("必须选择一项要删除的客户类别", "删除类别");
                return;
            }
            BtnCateDelWorking = true;
            void callback(RetModel rm)
            {
                if (delCateState.CurStep != Steps.Send)
                    return;
                delCateState.RM = rm;
                delCateState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            delCateState = new StateModel { CurStep = Steps.Send };
            CustomSrv.DelCate(callback, cm.Id);
            await delCateState.CheckState(10);
            BtnCateDelWorking = false;
            if (delCateState.CurStep == Steps.Succ)
            {
                GetCustCateList();
            }
            else
            {
                Comm.ShowErr(delCateState.ErrStr, "删除类别");
            }
        }

        #endregion 删除客户类别

        #region 读取客户类别

        private StateModel getCateListState;

        private async void GetCustCateList()
        {
            CateRunning = Visibility.Visible;
            CateLoading = true;
            CateList.Clear();
            void callback(RetModel rm)
            {
                if (getCateListState.CurStep != Steps.Send)
                    return;
                getCateListState.RM = rm;
                getCateListState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
                if (rm.Success)
                {
                    getCateListState.RM.Data = rm.Data is null ? null : JsonConvert.DeserializeObject<List<CustomCateModel>>(rm.Data?.ToString());
                }
            }
            getCateListState = new StateModel { CurStep = Steps.Send };
            CustomSrv.GetCateList(callback);
            await getCateListState.CheckState(10);
            if (getCateListState.CurStep != Steps.Succ)
            {
                Comm.ShowErr(getCateListState.ErrStr, "读取类别");
            }
            else
            {
                if (getCateListState.RM.Data is List<CustomCateModel> l && l?.Count > 0)
                    CateList.AddRange(l);
            }
            CateRunning = Visibility.Hidden;
            CateLoading = false;
        }

        #endregion 读取客户类别

        #region 读取客户列表

        private StateModel getCustListState;

        private async void GetCustList()
        {
            void callback(RetModel rm)
            {
                if (getCustListState.CurStep != Steps.Send)
                    return;
                getCustListState.RM = rm;
                getCustListState.RM.Data = rm.Data is null ? null : JsonConvert.DeserializeObject<List<CustomModel>>(rm.Data?.ToString());
                getCustListState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            CustList.Clear();
            ShowList.Clear();
            if (SelectedCate is null || !(SelectedCate is CustomCateModel ccm))
                return;
            CustRunning = Visibility.Visible;
            CustLoading = true;
            byte showDisable = ShowDisabledCustom ? (byte)255 : (byte)0;
            getCustListState = new StateModel { CurStep = Steps.Send };
            CustomSrv.GetCustList(callback, ccm.Id, showDisable);
            await getCustListState.CheckState(10);
            if (getCustListState.CurStep != Steps.Succ)
            {
                Comm.ShowErr(getCustListState.ErrStr, "读取客户列表");
            }
            else
            {
                if (getCustListState.RM.Data is List<CustomModel> l && l?.Count > 0)
                {
                    CustList.AddRange(l);
                    ShowList.AddRange(l);
                }
            }
            CustRunning = Visibility.Hidden;
            CustLoading = false;
        }

        #endregion 读取客户列表

        #region 查找客户列表

        private void SearchCust()
        {
            if (CustList is null || CustList?.Count < 1)
                return;
            ShowList.Clear();
            if (string.IsNullOrEmpty(Keyword))
            {
                ShowList.AddRange(CustList);
                return;
            }
            var l = CustList.Where(p => p.CustPhone.Contains(Keyword))?.ToList();
            if (l != null)
                ShowList.AddRange(l);
        }

        #endregion 查找客户列表

        #region 导出客户列表

        private void ExportCust()
        {
            if (CustList is null || CustList?.Count < 1)
            {
                Comm.ShowErr("没有要导出的数据", "客户导出");
                return;
            }
            try
            {
                SaveFileDialog fd = new SaveFileDialog();
                fd.Filter = "Excel 97-2003|*.xls|Excel 2007|*.xlsx";
                fd.FileName = string.Empty;
                fd.ShowDialog();
                if (string.IsNullOrEmpty(fd.FileName))
                    return;
                IWorkbook book = null;
                string fileName = fd.FileName;
                FileInfo fi = new FileInfo(fileName);
                if (fi.Extension.ToLower() == ".xls")
                    book = new HSSFWorkbook();
                else if (fi.Extension.ToLower() == ".xlsx")
                    book = new XSSFWorkbook();
                else
                {
                    Comm.ShowErr("文件类型错误", "导出客户");
                    return;
                }
                ISheet sheet = book.CreateSheet("客户列表");
                IRow row = sheet.CreateRow(0);
                //表头
                row.CreateCell(0).SetCellValue("内码");
                row.CreateCell(1).SetCellValue("编号");
                row.CreateCell(2).SetCellValue("名称");
                row.CreateCell(3).SetCellValue("类别");
                row.CreateCell(4).SetCellValue("电话");
                row.CreateCell(5).SetCellValue("备注");
                row.CreateCell(6).SetCellValue("兑换数量");
                row.CreateCell(7).SetCellValue("兑换总额");
                row.CreateCell(8).SetCellValue("状态");
                //内容
                for (int i = 0; i < CustList.Count; i++)
                {
                    int idx = i + 1;
                    var c = CustList[i];
                    row = sheet.CreateRow(idx);
                    row.CreateCell(0).SetCellValue(c.Id);
                    row.CreateCell(1).SetCellValue(c.CustCode);
                    row.CreateCell(2).SetCellValue(c.CustName);
                    row.CreateCell(3).SetCellValue(c.CateName);
                    row.CreateCell(4).SetCellValue(c.CustPhone);
                    row.CreateCell(5).SetCellValue(c.Remark);
                    row.CreateCell(6).SetCellValue(c.ChargeCount.ToString());
                    row.CreateCell(7).SetCellValue(c.ChargeAmount.ToString());
                    row.CreateCell(8).SetCellValue(c.CustState == 0 ? "正常" : "禁用");
                }
                //保存
                FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                book.Write(fs);
                fs.Close();
                Comm.ShowErr("导出完成", "导出客户", MessageBoxIcon.Success);
            }
            catch (Exception ex)
            {
                Comm.ShowErr(ex.Message, "导出客户");
            }
        }

        #endregion 导出客户列表

        #region 打开增加客户窗口

        private void CustAdd()
        {
            _custEditWindow = new Views.CustomEditView()
            {
                Title = "新增客户",
                Owner = Comm.Shell,
                DataContext = this
            };
            _custEditOpenType = "new";
            CustEditNew();
            _custEditWindow.ShowDialog();
        }

        #endregion 打开增加客户窗口

        #region 打开客户修改窗口

        private StateModel getCustState;

        private async void CustEdit()
        {
            void callback(RetModel rm)
            {
                if (getCustState.CurStep != Steps.Send)
                    return;
                getCustState.RM = rm;
                if (rm.Success)
                {
                    getCustState.RM.Data = rm.Data is null ? null : JsonConvert.DeserializeObject<CustomModel>(rm.Data.ToString());
                }
                getCustState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            void cateCallback(RetModel rm)
            {
                if (getCateListState.CurStep != Steps.Send)
                    return;
                getCateListState.RM = rm;
                if (rm.Success)
                {
                    getCateListState.RM.Data = rm.Data is null ? null : JsonConvert.DeserializeObject<List<CustomCateModel>>(rm.Data.ToString());
                }
                getCateListState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            if (SelectedCust is null || !(SelectedCust is CustomModel cm))
            {
                Comm.ShowErr("必须选择一个要修改的客户", "修改客户");
                return;
            }
            CustEditCateList.Clear();
            getCustState = new StateModel { CurStep = Steps.Send };
            CustomSrv.GetCustInfo(callback, cm.Id);
            await getCustState.CheckState(10);
            if (getCustState.CurStep != Steps.Succ)
            {
                Comm.ShowErr(getCustState.ErrStr, "修改客户");
                return;
            }
            CustEditCust = getCustState.RM.Data as CustomModel;
            //类别
            getCateListState = new StateModel { CurStep = Steps.Send };
            CustomSrv.GetCateList(cateCallback);
            await getCateListState.CheckState(10);
            if (getCateListState.CurStep != Steps.Succ)
            {
                Comm.ShowErr(getCateListState.ErrStr, "修改客户");
                return;
            }
            if (getCateListState.RM.Data is List<CustomCateModel> l && l?.Count > 0)
                CustEditCateList.AddRange(l);

            for (int i = 0; i < CustEditCateList.Count; i++)
            {
                if (CustEditCust.CateId == CustEditCateList[i].Id)
                {
                    CustEditSelectedCate = CustEditCateList[i];
                }
            }
            _custEditWindow = new Views.CustomEditView()
            {
                Title = "客户信息修改",
                Owner = Comm.Shell,
                DataContext = this
            };
            _custEditOpenType = "edit";
            _custEditWindow.ShowDialog();
        }

        #endregion 打开客户修改窗口

        #region 客户启用

        private StateModel enableCustState;

        private async void CustEnable()
        {
            void callback(RetModel rm)
            {
                if (enableCustState.CurStep != Steps.Send)
                    return;
                enableCustState.RM = rm;
                enableCustState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            if (SelectedCust is null || !(SelectedCust is CustomModel cm))
            {
                Comm.ShowErr("必须选择要启用的用户", "启用客户");
                return;
            }
            var rst = MessageBoxX.Show("是否确认要启用当前选择的客户？", "禁用客户", Comm.Shell, MessageBoxButton.YesNo, new MessageBoxXConfigurations
            {
                MaxContentWidth = 240,
                MaxContentHeight = 240,
                Topmost = false,
                MessageBoxStyle = MessageBoxStyle.Modern,
                WindowStartupLocation = WindowStartupLocation.CenterOwner
            });
            if (rst != MessageBoxResult.Yes)
                return;
            BtnCustEnableWorking = true;
            string err = "";
            enableCustState = new StateModel { CurStep = Steps.Send };
            CustomSrv.EnableCust(callback, cm.Id);
            await enableCustState.CheckState(10);
            if (enableCustState.CurStep == Steps.Succ)
            {
                GetCustList();
            }
            else
            {
                Comm.ShowErr(err, "启用客户");
            }
            BtnCustEnableWorking = false;
        }

        #endregion 客户启用

        #region 客户禁用

        private async void CustDisable()
        {
            void callback(RetModel rm)
            {
                if (enableCustState.CurStep != Steps.Send)
                    return;
                enableCustState.RM = rm;
                enableCustState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            if (SelectedCust is null || !(SelectedCust is CustomModel cm))
            {
                Comm.ShowErr("必须选择要禁用的客户！", "禁用客户");
                return;
            }
            if (MessageBoxX.Show("是否确认要禁用当前选择的客户？", "禁用客户", Comm.Shell, MessageBoxButton.YesNo, new MessageBoxXConfigurations
            {
                MaxContentWidth = 240,
                MaxContentHeight = 240,
                Topmost = false,
                MessageBoxStyle = MessageBoxStyle.Modern,
                WindowStartupLocation = WindowStartupLocation.CenterOwner
            }) != MessageBoxResult.Yes)
                return;
            BtnCustDisableWorking = true;
            enableCustState = new StateModel { CurStep = Steps.Send };
            CustomSrv.DisableCust(callback, cm.Id);
            await enableCustState.CheckState(10);
            if (enableCustState.CurStep == Steps.Succ)
            {
                GetCustList();
            }
            else
            {
                Comm.ShowErr(enableCustState.ErrStr, "禁用客户");
            }
            BtnCustDisableWorking = false;
        }

        #endregion 客户禁用

        #region 刷新客户列表

        private void CustRefreshList()
        {
            BtnCustRefreshWorking = true;
            GetCustList();
            BtnCustRefreshWorking = false;
        }

        #endregion 刷新客户列表

        #endregion 客户管理窗口

        #region 类别编辑窗口

        #region 清空界面，新增客户分类

        private void CateEditNew()
        {
            CateEditCate = new CustomCateModel();
            _cateEditOpenType = "new";
        }

        #endregion 清空界面，新增客户分类

        #region 保存类别

        private StateModel saveCateState;

        private async void CateEditSave()
        {
            void callback(RetModel rm)
            {
                if (saveCateState.CurStep != Steps.Send)
                    return;
                saveCateState.RM = rm;
                saveCateState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            bool needClose = false;
            saveCateState = new StateModel { CurStep = Steps.Send };
            if (_cateEditOpenType == "new")
            {
                CustomSrv.AddCate(callback, CateEditCate);
            }
            else
            {
                needClose = true;
                CustomSrv.EditCate(callback, CateEditCate);
            }
            await saveCateState.CheckState(10);
            if (saveCateState.CurStep == Steps.Succ)
            {
                CateEditNew();
                GetCustCateList();
            }
            else
            {
                Comm.ShowErr(saveCateState.ErrStr, "保存客户类别");
            }
            if (needClose)
                _cateEditWindow.Close();
        }

        #endregion 保存类别

        #endregion 类别编辑窗口

        #region 客户信息编辑窗口

        #region 新增客户

        private void CustEditNew()
        {
            CustEditCust = new CustomModel() { CustCode = Guid.NewGuid().ToString("N") };
            _custEditOpenType = "new";
            CustEditGetCateList();
        }

        #endregion 新增客户

        #region 保存客户

        private StateModel saveCustState;

        private int CheckSaveCust()
        {
            if (CustEditCust is null)
            {
                CustEditNew();
                throw new Exception("请填写必要信息后再保存");
            }
            if (CustEditSelectedCate is null)
            {
                throw new Exception("客户类别必须选择！");
            }
            if (!(CustEditSelectedCate is CustomCateModel ccm))
            {
                throw new Exception("客户类别必须选择！");
            }
            if (CustEditCust.CustCode.IsNullOrEmpty())
            {
                throw new Exception("客户编号必须填写！");
            }
            if (CustEditCust.CustName.IsNullOrEmpty())
            {
                throw new Exception("客户名称必须填写！");
            }
            return ccm.Id;
        }

        private async void CustEditSave()
        {
            void callback(RetModel rm)
            {
                if (saveCustState.CurStep != Steps.Send) return;
                saveCustState.RM = rm;
                saveCustState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            try
            {
                CustEditCust.CateId = CheckSaveCust();
            }
            catch (Exception ex)
            {
                Comm.ShowErr(ex.Message, "保存客户信息");
                return;
            }
            BtnCustEditSaveWorking = true;
            saveCustState = new StateModel { CurStep = Steps.Send };
            if (_custEditOpenType == "edit")
            {
                CustomSrv.EditCust(callback, CustEditCust);
            }
            else
            {
                CustomSrv.AddCust(callback, CustEditCust);
            }
            await saveCustState.CheckState(10);
            if (saveCustState.CurStep == Steps.Succ)
            {
                GetCustList();
                if (_custEditOpenType == "new")
                    CustEditNew();
                else
                    _custEditWindow.Close();
            }
            else
            {
                Comm.ShowErr(saveCustState.ErrStr, "保存客户");
            }
            BtnCustEditSaveWorking = false;
        }

        #endregion 保存客户

        #region 读取类别列表

        private async void CustEditGetCateList()
        {
            void callback(RetModel rm)
            {
                if (getCateListState.CurStep != Steps.Send)
                    return;
                getCateListState.RM = rm;
                if (rm.Success)
                    getCateListState.RM.Data = rm.Data is null ? null : JsonConvert.DeserializeObject<List<CustomCateModel>>(rm.Data.ToString());
                getCateListState.CurStep = rm.Success ? Steps.Succ : Steps.Fail;
            }
            CustEditCateList.Clear();
            getCateListState = new StateModel { CurStep = Steps.Send };
            CustomSrv.GetCateList(callback);
            await getCateListState.CheckState(10);
            if (getCateListState.CurStep != Steps.Succ)
            {
                Comm.ShowErr(getCateListState.ErrStr, "读取类别");
                return;
            }
            else
            {
                var l = getCateListState.RM.Data as List<CustomCateModel>;
                if (l?.Count > 0)
                    CustEditCateList.AddRange(l);
                if (CustEditCateList?.Count > 0)
                    CustEditSelectedCate = CustEditCateList[0];
            }
        }

        #endregion 读取类别列表

        #endregion 客户信息编辑窗口

        #endregion 方法
    }
}